//抽象工厂模式  Abstract Factory Pattern
//提供一个创建一些列相关或者相互依赖的对象的接口，而无需指定它们的具体类

#include <iostream>
#include <string>
#include <memory>

class AbstractUser
{
public:
    using ptr = std::shared_ptr<AbstractUser>;
    virtual void insertData() = 0;
    virtual void getData() = 0;
};

class UserMysql : public AbstractUser
{
public:
    using ptr = std::shared_ptr<UserMysql>;
    virtual void insertData() override
    {
        std::cout << "向MySQL中插入yonghu数据成功" << std::endl;
    }
    virtual void getData() override
    {
        std::cout << "从MySQL中获取yonghu数据成功" << std::endl;
    }
};
class UserSqlite : public AbstractUser
{
public:
    using ptr = std::shared_ptr<UserSqlite>;
    virtual void insertData() override
    {
        std::cout << "向SQLite中插入yonghu数据成功" << std::endl;
    }
    virtual void getData() override
    {
        std::cout << "从SQLite中获取yonghu数据成功" << std::endl;
    }
};

class AbstractDepartment
{
public:
    using ptr = std::shared_ptr<AbstractDepartment>;
    virtual void insertData() = 0;
    virtual void getData() = 0;
};

class DepartmentMysql : public AbstractDepartment
{
public:
    using ptr = std::shared_ptr<DepartmentMysql>;
    virtual void insertData() override
    {
        std::cout << "向MySQL中插入bumen数据成功" << std::endl;
    }
    virtual void getData() override
    {
        std::cout << "从MySQL中获取bumen数据成功" << std::endl;
    }
};

class DepartmentSqlite : public AbstractDepartment
{
public:
    using ptr = std::shared_ptr<DepartmentSqlite>;
    virtual void insertData() override
    {
        std::cout << "向SQLite中插入bumen数据成功" << std::endl;
    }
    virtual void getData() override
    {
        std::cout << "从SQLite中获取bumen数据成功" << std::endl;
    }
};

class Factory
{
public:
    using ptr = std::shared_ptr<Factory>;
    virtual AbstractUser::ptr createUser() = 0;
    virtual AbstractDepartment::ptr createDepartment() = 0;
};

class MysqlFactory : public Factory
{
public:
    using ptr = std::shared_ptr<MysqlFactory>;
    virtual AbstractUser::ptr createUser() override
    {
        return UserMysql::ptr(new UserMysql);
    }
    virtual AbstractDepartment::ptr createDepartment() override
    {
        return DepartmentMysql::ptr(new DepartmentMysql);
    }
};

class SqliteFactory : public Factory
{
public:
    using ptr = std::shared_ptr<SqliteFactory>;
    virtual AbstractUser::ptr createUser() override
    {
        return UserSqlite::ptr(new UserSqlite);
    }
    virtual AbstractDepartment::ptr createDepartment() override
    {
        return DepartmentSqlite::ptr(new DepartmentSqlite);
    }
};

int main()
{
    //模拟调用sqlite的相关API
    // Factory::ptr factory(new SqliteFactory);
    //模拟调用mysql的相关API
    Factory::ptr factory(new MysqlFactory);
    AbstractUser::ptr user = factory->createUser();
    AbstractDepartment::ptr department=factory->createDepartment();
    user->insertData();
    user->getData();
    department->insertData();
    department->getData();
    return 0;
}